#pragma once

namespace IDK
{
	template <typename T, typename _Self> 
	public ref class ManagedTreeList : public ManagedObject, public IEnumerable
	{
	public:
		ref class Item : public ManagedObject
		{
		public:
			typedef UnManaged::System::TTreeListItem<UnManaged::System::ref<_Self>> Self;
		public:
			Item(Self* self) : ManagedObject(mSelf = self) {}

			T^ Current()
			{
				return gcnew T(mSelf->Current().GetUnmanagedPointer());
			}

			ManagedTreeList^ GetChildren()
			{
				return gcnew ManagedTreeList(mSelf->GetChildren().GetUnmanagedPointer());
			}
		private:
			Self* mSelf;
		};

		typedef UnManaged::System::TList<UnManaged::System::ref<_Self>, typename Item::Self> Self;
	public:

		ManagedTreeList(Self* self) : ManagedObject(mSelf = self)
		{
		}

		virtual Item^ Get(int)
		{ 
			return nullptr;
		}

		//{
		//	return gcnew Item(mSelf->Get(index).GetUnmanagedPointer());
		//}

		int Length(void)
		{
			return mSelf->Length();
		}

		ref class Enumerator : public IEnumerator
		{
		private:
			ManagedTreeList^ mContainer;
			int mIndex;
		public:
			Enumerator(ManagedTreeList^ container)
				: mContainer(container)
			{
				mIndex = -1;
			}

			virtual property Object^ Current
			{
				Object^ get()
				{
					return mContainer->Get(mIndex);
				}
			}

			virtual bool MoveNext()
			{
				return ++mIndex < mContainer->Length();
			}

			virtual void Reset()
			{
				mIndex = -1;
			}
		};

		virtual IEnumerator^ GetEnumerator(void)
		{
			return gcnew Enumerator(this);
		}
	public:
		Self* GetSelf() overload
		{
			return mSelf;
		}
	private:
		Self* mSelf;
	};
}